package com.sinoglobal.ningxia.qr;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.PointF;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Vibrator;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

import com.alibaba.fastjson.JSON;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.DecodeHintType;
import com.google.zxing.FormatException;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import com.sinoglobal.ningxia.R;
import com.sinoglobal.ningxia.frame.FlyApplication;
import com.sinoglobal.ningxia.utils.FlyUtil;
import com.sinoglobal.ningxia.utils.ItktLog;
import com.sinoglobal.ningxia.utils.MContants;
import com.sinoglobal.ningxia.utils.SharedPreferenceUtil;
import com.sinoglobal.ningxia.utils.ToastBuilder;
import com.sinoglobal.ningxia.utils.ValidUtil;
import com.zbar.lib.CameraManager;
import com.zbar.lib.InactivityTimer;
import com.zbar.lib.RGBLuminanceSource;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Calendar;
import java.util.Hashtable;

/**
 * @author limeishu
 * @createdate 2014-8-27 下午2:08:35
 * @Description: (扫描界面)
 */
public class CaptureActivity extends Activity implements Callback {

	private CaptureActivityHandler handler;// 扫描控制类
	private boolean hasSurface;// 摄像头是否已经初始化
	private InactivityTimer inactivityTimer;
	private MediaPlayer mediaPlayer;
	private boolean playBeep;// 是否开启声音
	private static final float BEEP_VOLUME = 0.50f;// 音量大小
	private boolean vibrate;// 是否开启震动
	private int x = 0;
	private int y = 0;
	private int cropWidth = 0;
	private int cropHeight = 0;
	private RelativeLayout mContainer = null;// 扫描界面
	private RelativeLayout mCropLayout = null;// 扫描框
	private VerticalSeekBar seekBar;// 调焦控件
	private ImageView history;// 历史记录
	private ImageView photos;// 相册
	private TextView lightBtn;// 闪光灯按钮
	private ImageView lightImg;// 闪光灯开关图片
	private boolean isNeedCapture = false;
	private boolean isTorchOn = true;// 开关灯

	public static final int PHOTO_RESULT = 20; // 选择相册图片结果
	public static final String IMAGE_UNSPECIFIED = "image/*";
	private Bitmap scanBitmap;
	private String photoPath = "";// 图片地址
	private String contentResult;// 扫描结果
	private int type = 0;// 扫描结果类型,1为网址,2为文本
	private HistoryListVo historyListVo = new HistoryListVo();
	private Calendar calendar;// 日历对象
	private int year;// 年
	private int month;// 月
	private int day;// 日
	private Intent intent;// 意图
	SurfaceView surfaceView;
	private ImageView topLeft;// 返回键

	public boolean isNeedCapture() {
		return isNeedCapture;
	}

	public void setNeedCapture(boolean isNeedCapture) {
		this.isNeedCapture = isNeedCapture;
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}

	public int getCropWidth() {
		return cropWidth;
	}

	public void setCropWidth(int cropWidth) {
		this.cropWidth = cropWidth;
	}

	public int getCropHeight() {
		return cropHeight;
	}

	public void setCropHeight(int cropHeight) {
		this.cropHeight = cropHeight;
	}

	public ImageView getHistory() {
		return history;
	}

	public void setHistory(ImageView history) {
		this.history = history;
	}

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		FlyUtil.addAppActivity(this);
		getWindow().requestFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.qr_activity_scan);
		ImageView mQrLineView = (ImageView) findViewById(R.id.capture_scan_line);
		init();
		setListener();
		TranslateAnimation mAnimation = new TranslateAnimation(TranslateAnimation.ABSOLUTE, 0f, TranslateAnimation.ABSOLUTE, 0f,
				TranslateAnimation.RELATIVE_TO_PARENT, 0f, TranslateAnimation.RELATIVE_TO_PARENT, 0.9f);
		mAnimation.setDuration(1500);
		mAnimation.setRepeatCount(-1);
		mAnimation.setRepeatMode(Animation.REVERSE);
		mAnimation.setInterpolator(new LinearInterpolator());
		mQrLineView.setAnimation(mAnimation);
		initState();
	}

	/**
	 * 沉浸式状态栏
	 */
	public void initState() {
		if (Build.VERSION.SDK_INT >= 21) {
			View decorView = getWindow().getDecorView();
			int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
			decorView.setSystemUiVisibility(option);
			getWindow().setStatusBarColor(Color.parseColor("#dd191d"));
		}

	}
	private void setListener() {
		// 变焦进度条
		seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {

			}

			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {

			}

			@Override
			public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
				ItktLog.i("===========progress=============" + progress);
				try {
					if (rate > CameraManager.get().getZoom()) {
						rate = CameraManager.get().getZoom();
					} else if (rate < 0) {
						rate = 0;
					}
					rate = seekBar.getProgress();
					CameraManager.get().changeZoom((int) rate);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
		// 开关灯
		lightBtn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (isTorchOn) {
					isTorchOn = false;
					if (!CameraManager.get().isHaveLight(getApplicationContext())) {
						ToastBuilder.getIntance(FlyApplication.context).showToast(getString(R.string.qr_no_light));
						return;
					}
					lightImg.setImageResource(R.drawable.btn_opened);
					CameraManager.get().openLight();// 开灯
				} else {
					isTorchOn = true;
					lightImg.setImageResource(R.drawable.btn_closed);
					CameraManager.get().offLight();// 关灯
				}
			}
		});
		// 相册
		photos.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				setFromPhotoes();
			}
		});
		// 历史记录
		history.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				intent = new Intent(CaptureActivity.this, HistoryCodeActivity.class);
				startActivity(intent);
			}
		});

	}

	private void init() {

		// 初始化 CameraManager
		CameraManager.init(this);
		DisplayMetrics dm = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(dm);
		hasSurface = false;
		topLeft = (ImageView) findViewById(R.id.btn_sliding);
		topLeft.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				finish();
			}
		});
		surfaceView = (SurfaceView) findViewById(R.id.capture_preview);
		inactivityTimer = new InactivityTimer(this);
		mContainer = (RelativeLayout) findViewById(R.id.capture_containter);
		mCropLayout = (RelativeLayout) findViewById(R.id.capture_crop_layout);
		seekBar = (VerticalSeekBar) findViewById(R.id.verticalSeekBar1);
		history = (ImageView) findViewById(R.id.history_img);
		photos = (ImageView) findViewById(R.id.photos_img);
		lightBtn = (TextView) findViewById(R.id.light_click_view);
		lightImg = (ImageView) findViewById(R.id.light_img);
		// 设置闪光灯按钮的大小
		RelativeLayout.LayoutParams params = (LayoutParams) lightImg.getLayoutParams();
		params.width = dm.widthPixels;
		params.height = dm.widthPixels / 4;
		calendar = Calendar.getInstance();
	}

	@SuppressWarnings("deprecation")
	@Override
	public void onResume() {
		super.onResume();
		SurfaceView surfaceView = (SurfaceView) findViewById(R.id.capture_preview);
		SurfaceHolder surfaceHolder = surfaceView.getHolder();
		/*
		 * surfaceView.setOnTouchListener(new OnTouchListener() {
		 * 
		 * @Override public boolean onTouch(View arg0, MotionEvent event) {
		 * surfaceView.onTouchEvent(event); return false; } });
		 */
		lightImg.setImageResource(R.drawable.btn_closed);
		isTorchOn = true;
		if (hasSurface) {
			initCamera(surfaceHolder);
		} else {
			surfaceHolder.addCallback(this);
			surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		}
		playBeep = true;
		AudioManager audioService = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
		if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
			playBeep = false;
		}
		initBeepSound();
		vibrate = true;
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {

		super.onActivityResult(requestCode, resultCode, data);

		if (resultCode == RESULT_OK) {

			switch (requestCode) {

			case PHOTO_RESULT:

				String[] proj = { MediaStore.Images.Media.DATA };
				// 获取选中图片的路径
				Cursor cursor = getContentResolver().query(data.getData(), proj, null, null, null);

				if (cursor.moveToFirst()) {

					int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
					photoPath = cursor.getString(column_index);
					if (photoPath == null) {
						photoPath = UriUtil.getPath(this, data.getData());
					}
				}

				cursor.close();

				new Thread(new Runnable() {

					@Override
					public void run() {

						Result result = scanningImage(photoPath);
						if (result == null) {
							Looper.prepare();
							ToastBuilder.getIntance(FlyApplication.context).showToast(getString(R.string.qr_no_code));
							Looper.loop();
							return;
						}
						// 数据返回
						contentResult = recode(result.toString());
						if (contentResult == null || MContants.EMPTY_STRING.equals(contentResult)) {
							return;
						}
						// 判断获取结果是网址或者文本信息
						String validUrlResult = ValidUtil.validUrl(contentResult);
						if (MContants.EMPTY_STRING.equals(validUrlResult)) {
							type = 1;
						} else {
							type = 2;
						}
						saveHistoryData(String.valueOf(type), contentResult);
						if (1 == type) {
							intent = new Intent(CaptureActivity.this, QrUrlResultActivity.class);
						} else if (2 == type) {
							intent = new Intent(CaptureActivity.this, QrStrResultActivity.class);
						}
						intent.putExtra("captureResult", contentResult);
						startActivity(intent);
					}
				}).start();

				break;

			}

		}

	}

	@Override
	public void onPause() {
		super.onPause();
		if (handler != null) {
			handler.quitSynchronously();
			handler = null;
		}
		CameraManager.get().closeDriver();
	}

	@Override
	public void onDestroy() {
		inactivityTimer.shutdown();
		FlyUtil.removeAppActivity(this);
		super.onDestroy();

	}

	// 处理扫描结果
	public void handleDecode(String result) {
		inactivityTimer.onActivity();
		playBeepSoundAndVibrate();
		if (result == null || MContants.EMPTY_STRING.equals(result)) {
			result = getString(R.string.qr_cannt_identify);
		} else {
			// 判断获取结果是网址或者文本信息
			String validUrlResult = ValidUtil.validUrl(result);
			if (MContants.EMPTY_STRING.equals(validUrlResult)) {
				type = 1;
			} else {
				type = 2;
			}
			// 将扫描结果和类型保存到本地
			saveHistoryData(String.valueOf(type), result);
			if (1 == type) {
				intent = new Intent(CaptureActivity.this, QrUrlResultActivity.class);
			} else if (2 == type) {
				intent = new Intent(CaptureActivity.this, QrStrResultActivity.class);
			}
			intent.putExtra("captureResult", result);
			startActivity(intent);
		}
	}

	// 保存历史数据到本地
	private void saveHistoryData(String type, String result) {
		getTimer();
		HistoryMessageVo messageVo = new HistoryMessageVo();
		messageVo.setType(type);
		messageVo.setContent(result);
		messageVo.setDay(day);
		messageVo.setMonth(month);
		messageVo.setYear(year);
		String data = SharedPreferenceUtil.getString(getApplicationContext(), "historyListStr");
		if (data != null && data.length() > 0) {
			historyListVo = JSON.parseObject(data, HistoryListVo.class);
		} else {
			historyListVo = new HistoryListVo();
		}
		historyListVo.getJson().add(0, messageVo);
		SharedPreferenceUtil.saveString(getApplicationContext(), "historyListStr", JSON.toJSONString(historyListVo));
	}

	// 初始化设置相机
	private void initCamera(SurfaceHolder surfaceHolder) {
		try {
			CameraManager.get().openDriver(surfaceHolder);

			Point point = CameraManager.get().getCameraResolution();
			int width = point.y;
			int height = point.x;

			int x = mCropLayout.getLeft() * width / mContainer.getWidth();
			int y = mCropLayout.getTop() * height / mContainer.getHeight();

			int cropWidth = mCropLayout.getWidth() * width / mContainer.getWidth();
			int cropHeight = mCropLayout.getHeight() * height / mContainer.getHeight();

			setX(x);
			setY(y);
			setCropWidth(cropWidth);
			setCropHeight(cropHeight);
			// 设置是否需要截图
			setNeedCapture(true);

		} catch (IOException ioe) {
			return;
		} catch (RuntimeException e) {
			return;
		}
		if (handler == null) {
			handler = new CaptureActivityHandler(CaptureActivity.this);
		}
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		if (!hasSurface) {
			hasSurface = true;
			try {
				initCamera(holder);
				seekBar.setMax(CameraManager.get().getZoom());
			} catch (Exception e) {
				e.printStackTrace();
				ToastBuilder.getIntance(FlyApplication.context).showToast(getString(R.string.qr_init_camera_fail));

			}
		}
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		hasSurface = false;

	}

	public Handler getHandler() {
		return handler;
	}

	// 初始化设置声音
	private void initBeepSound() {
		if (playBeep && mediaPlayer == null) {
			setVolumeControlStream(AudioManager.STREAM_MUSIC);
			mediaPlayer = new MediaPlayer();
			mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
			mediaPlayer.setOnCompletionListener(beepListener);

			AssetFileDescriptor file = getResources().openRawResourceFd(R.raw.beep);
			try {
				mediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength());
				file.close();
				mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
				mediaPlayer.prepare();
			} catch (IOException e) {
				mediaPlayer = null;
			}
		}
	}

	private static final long VIBRATE_DURATION = 200L;

	// 设置声音和震动
	private void playBeepSoundAndVibrate() {
		if (playBeep && mediaPlayer != null) {
			mediaPlayer.start();
		}
		if (vibrate) {
			Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
			vibrator.vibrate(VIBRATE_DURATION);
		}
	}

	// 调用媒体
	private final OnCompletionListener beepListener = new OnCompletionListener() {
		public void onCompletion(MediaPlayer mediaPlayer) {
			try {
				mediaPlayer.seekTo(0);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	};

	// 从相册中选择图片
	public void setFromPhotoes() {
		// 调用系统的相册
		intent = new Intent(Intent.ACTION_PICK, null);
		intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_UNSPECIFIED);
		// 调用剪切功能
		startActivityForResult(intent, PHOTO_RESULT);
	}

	// 扫描并获取结果
	@SuppressLint("NewApi")
	protected Result scanningImage(String path) {
		if (TextUtils.isEmpty(path)) {
			return null;
		}
		// DecodeHintType 和EncodeHintType
		Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();
		hints.put(DecodeHintType.CHARACTER_SET, "ISO-8859-1"); // 设置二维码内容的编码
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true; // 先获取原大小
		scanBitmap = BitmapFactory.decodeFile(path, options);
		options.inJustDecodeBounds = false; // 获取新的大小

		int sampleSize = (int) (options.outHeight / (float) 200);

		if (sampleSize <= 0)
			sampleSize = 1;
		options.inSampleSize = sampleSize;
		scanBitmap = BitmapFactory.decodeFile(path, options);

		RGBLuminanceSource source = new RGBLuminanceSource(scanBitmap);
		BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));
		QRCodeReader reader = new QRCodeReader();
		try {

			return reader.decode(bitmap1, hints);

		} catch (NotFoundException e) {

			e.printStackTrace();

		} catch (ChecksumException e) {

			e.printStackTrace();

		} catch (FormatException e) {

			e.printStackTrace();

		}

		return null;

	}

	// 重新编码
	private String recode(String str) {
		String UTF_Str = "";
		String GB_Str = "";
		boolean is_cN = false;
		try {
			ItktLog.i("------------" + str);
			UTF_Str = new String(str.getBytes("ISO-8859-1"), "UTF-8");
			ItktLog.i("这是转了UTF-8的" + UTF_Str);
			is_cN = IsChineseOrNot.isChineseCharacter(UTF_Str);
			// 防止有人特意使用乱码来生成二维码来判断的情况
			boolean b = IsChineseOrNot.isSpecialCharacter(str);
			if (b) {
				is_cN = true;
			}
			ItktLog.i("是为:" + is_cN);
			if (!is_cN) {
				GB_Str = new String(str.getBytes("ISO-8859-1"), "GB2312");
				ItktLog.i("这是转了GB2312的" + GB_Str);
			}
		} catch (UnsupportedEncodingException e) {
			// Auto-generated catch block
			e.printStackTrace();
		}

		if (is_cN) {
			return UTF_Str;
		} else {
			return GB_Str;
		}
	}

	public static class IsChineseOrNot {

		public final static boolean isChineseCharacter(String chineseStr) {
			char[] charArray = chineseStr.toCharArray();
			for (int i = 0; i < charArray.length; i++) {
				// 是否是Unicode编码,除了"�"这个字符.这个字符要另外处理
				if ((charArray[i] >= '\u0000' && charArray[i] < '\uFFFD') || ((charArray[i] > '\uFFFD' && charArray[i] < '\uFFFF'))) {
					continue;
				} else {
					return false;
				}
			}
			return true;
		}

		public final static boolean isSpecialCharacter(String str) {
			// 是"�"这个特殊字符的乱码情况
			if (str.contains("ï¿½")) {
				return true;
			}
			return false;
		}
	}

	Matrix matrix = new Matrix();
	Matrix savedMatrix = new Matrix();
	PointF start = new PointF();
	PointF mid = new PointF();
	float oldDist;
	static final int NONE = 0;
	static final int DRAG = 1;
	static final int ZOOM = 2;
	int mode = NONE;

	// 记录两个触屏点的坐标
	private int x1, x2, y1, y2;
	// 倍率
	private float rate = 1;
	// 记录上次的缩放比例
	private float oldRate = 1;
	// 记录第一次触屏时线段的长度
	private float oldLineDistance;
	// 判定是否头次多指触点屏幕
	private boolean isFirst = true;

	// 获取当前日期
	private void getTimer() {
		year = calendar.get(Calendar.YEAR);
		month = calendar.get(Calendar.MONTH) + 1;
		day = calendar.get(Calendar.DAY_OF_MONTH);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {

		if (event.getAction() == MotionEvent.ACTION_DOWN) {
			isFirst = true;
			oldRate = rate;
		} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
			if (event.getPointerCount() > 1) {
				x1 = (int) event.getX(0);
				y1 = (int) event.getY(0);
				x2 = (int) event.getX(1);
				y2 = (int) event.getY(1);
				if (event.getPointerCount() == 2) {
					if (isFirst) {
						// 得到第一次触屏时线段的长度
						oldLineDistance = (float) Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
						isFirst = false;
					} else {
						// 得到非第一次触屏时线段的长度
						float newLineDistance = (float) Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
						// 获取本次的缩放比例
						oldRate = (newLineDistance - oldLineDistance) / 60;
						rate += oldRate;
						try {
							if (rate > CameraManager.get().getZoom()) {
								rate = CameraManager.get().getZoom();
							} else if (rate < 0) {
								rate = 0;
							}
						} catch (Exception e) {
							e.printStackTrace();
							rate = 0;
						}
						ItktLog.i("=======newLineDistance- oldLineDistance======" + (newLineDistance - oldLineDistance));
					}
				}
			}
		}
		try {
			CameraManager.get().changeZoom((int) rate);
		} catch (Exception e) {
			e.printStackTrace();
		}
		seekBar.setProgress((int) rate);
		return true;
	}
}